![]() | |
|
|
|
To access the contents, click the chapter and section titles.
Bug Proofing Visual Basic: A Guide to Error Handling and Prevention
Note that this is probably not the best way to handle this situation because it silently handles the error instead of making it obvious. If the user entered the invalid value, the program should politely tell the user there is a problem and ask for a new value. If the string was passed to this routine from another part of the program, the program may contain a bug. It should stop during design mode or raise an error in the final compiled version so someone can fix the problem. Exit Sub/Function/PropertyIf the routine cannot continue with its task, it can use Exit Sub, Exit Function, or Exit Property to exit immediately. The following code shows a new version of the previous routine. If the date string is invalid, this version tells the user and then exits.
Private Sub ValidateStartDate(ByVal date_string As String)
Dim start_date As Date
' Install the error handler.
On Error GoTo InvalidDate
' Convert the string into a date.
start_date = CDate(date_string)
' Do something with the date.
:
' Do not pass through into the error handler code.
Exit Sub
InvalidDate:
' It's an invalid date string. Tell the user and leave.
MsgBox "The start date """ & _
date_string & _
""" is invalid. Please enter a new one."
Exit Sub
End Sub
When a routine exits in this way, the calling routine cannot tell that an error occurred. That means you should use this technique only when the calling routine can properly continue whether this routine succeeded or not. If the caller must know that this routine failed, the code should use the Err.Raise statement described shortly. End Sub/Function/PropertyIf the error handler code continues to the routines End Sub, End Function, or End Property statement, the routine exits just as if it had executed the Exit statement described in the previous section. For example, the end of the previous subroutine could be written:
InvalidDate:
' It's an invalid date string. Tell the user and leave.
MsgBox "The start date """ & _
date_string & _
""" is invalid. Please enter a new one."
End Sub
Sometimes it can be a little confusing for the error handler to just drop off the end of the routine like this. This version also creates the opportunity for a new bug. A developer who later adds a new error handler to the end of the routine may not notice that the code drops through the end of the routine. If the new error handler is added without a preceding Exit statement, the old error handler will continue into the new one. If the following code encounters an invalid date, it presents the user with two error messages instead of one.
InvalidDate:
' It's an invalid date string. Tell the user and leave.
MsgBox "The start date """ & _
date_string & _
""" is invalid. Please enter a new one."
ReadFileError:
' Error reading the data file.
MsgBox "Error reading the data."
:
End Sub
To prevent this kind of mistake, do not allow an error handler to continue to the routines End statement. Use an Exit statement to leave the routine instead. Err.RaiseThe Err object provides a Raise method that allows a program to generate errors. It can create new errors or reraise old ones. The syntax for the Raise method is Err.Raise Number, [Source], [Description], [Helpfile], [Helpcontext] Number. The error number. To create a new error code in a class module, add vbObjectError to your number. For example, vbObjectError + 1001. Source. The name of the object or application generating the error. For objects, use the format Project.Class. For routines, use the format Project.Routine. For example, MyProgram.LoadData. Description. A string describing the error. If you set Number to a standard Visual Basic error code like 9 for subscript out of range, you can omit Description to make Visual Basic use a standard description string. Helpfile. The full name of a help file that gives more information on the error. Helpcontext. The context ID for this errors topic in the help file. If a routine cannot handle an error itself, it should raise a new error that makes sense within its context. For example, the following routine attempts to read a data file. If the file is not found, the FileOpenError error handler raises the myappErrNoInputFile error. This gives the calling subroutine more information than Visual Basics initial file not found error. The error Visual Basic generates indicates that some file was not found. The new error explains that an input data file was not found. The Err.Description field even includes the name of the file that was not found.
' Define application error constants.
Private Const myappErrNoInputFile = vbObjectError + 1000
:
' Define Visual Basic error constants.
Private Const vbErrFileNotFound = 53
:
Private Sub ReadInputData(ByVal file_name As String)
Dim file_number As Integer
' Open the file.
file_number = FreeFile
On Error GoTo FileOpenError
Open file_name For Input As file_number
' Process the file.
On Error GoTo FileReadError
:
' Process the file here.
:
' Close the file.
Close file_number
Exit Sub
FileOpenError:
' There was an error opening the file.
If Err.Number = vbErrFileNotFound Then
' It's a file not found error. Convert it
' to myappErrNoInputFile.
Err.Raise myappErrNoInputFile, _
"MyApp.ReadInputData", _
"Could not open input file """ & _
file_name & """."
Else
' It's some other error. Reraise it so some
' other routine can catch it.
Err.Raise Err.Number, _
Err.Source, _
Err.Description, _
Err.HelpFile, _
Err.HelpContext
End If
Exit Sub
FileReadError:
' There was an error reading the file.
:
Exit Sub
End Sub
A program could invoke this subroutine using code similar to the following. The error handler uses the information stored in the Err object by the Raise method to present a message to the user.
On Error GoTo DataInputError
ReadInputData "c:\mydata.dat"
Exit Sub
DataInputError:
' There was an error loading the data.
MsgBox "Error" & Str$(Err.Number) & _
" loading the input data." & vbCrLf & _
Err.Description
Routines that present messages to users normally format the error information as shown in the previous code. To make that formatting as simple as possible, routines should not format the error description in the Raise statement. For example, the following code formats an errors description.
Err.Raise myappErrNoInputFile, _
"MyApp.ReadInputData", _
"Error" & Str$(myappErrNoInputFile) & _
" opening the input file."
|
|
Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.
|